package com.kingstar.ceres.data.annotation;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Utils {

    public enum FieldAccessType {

        GETTER, SETTER
    }

    public static List<CsvHeader> getHeaderList(Class<?> clz) throws Exception {

        List<CsvHeader> headers = new ArrayList<>();
        List<Field> fields = new ArrayList<>();
        for (Class<?> clazz = clz; clazz != Object.class; clazz = clazz.getSuperclass()) {
            fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
        }
        for (Field field : fields) {
            // 是否使用ExcelField注解
            if (field.isAnnotationPresent(CsvField.class)) {
                CsvField er = field.getAnnotation(CsvField.class);
                headers.add(new CsvHeader(
                        er.title(),
                        er.order(),
                        field.getName(),
                        er.ignore(),
                        field.getType()
                ));
            }
        }
        Collections.sort(headers);
        return headers;
    }

    public static String getProperty(Object bean, CsvHeader header) throws Exception {
        if (header.getIgnore()){
            return "";
        }
        return getProperty(bean,header.getFiled());
    }

    public static String getProperty(Object bean, String fieldName)
    throws Exception{

        if (bean == null || fieldName == null)
            throw new IllegalArgumentException("Operating bean or filed class must not be null");
        Method method;
        Object object;
        method = getterOrSetter(bean.getClass(), fieldName, FieldAccessType.GETTER);
        object = method.invoke(bean);

        return (object == null ? "" : object.toString()).replaceAll(";",",");
    }

    public static Method getterOrSetter(Class clazz, String fieldName, FieldAccessType methodType)
            throws IntrospectionException {

        if (null == fieldName || "".equals(fieldName))
            return null;

        BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
        PropertyDescriptor[] props = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor prop : props) {
            if (fieldName.equals(prop.getName())) {
                if (FieldAccessType.SETTER == methodType) {
                    return prop.getWriteMethod();
                }
                if (FieldAccessType.GETTER == methodType) {
                    return prop.getReadMethod();
                }
            }
        }
        throw new IntrospectionException("Can not get the getter or setter method");
    }
}
